package de.arndt_panzer.bensgallery;

import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.util.Log;
import android.util.LruCache;
import android.widget.ImageView;

public class BitmapWorkerTask	extends
								AsyncTask<BitmapWorkerParameter, BitmapWorkerTask.ProgressHolder, Bitmap[]> {
	
	public static final String	TAG	= BitmapWorkerTask.class.getSimpleName();
	
	public static class ProgressHolder {
		public final int	TaskNo;
		public final Bitmap	Bitmap;
		
		public ProgressHolder(int taskNo, Bitmap bmp) {
			TaskNo = taskNo;
			Bitmap = bmp;
		}
	}
	
	public static LruCache<String, Bitmap>	MEM_CHACHE;
	
	protected BitmapWorkerParameter[]		mParams;
	
	public BitmapWorkerTask() {
		// initialize cache
		initMemCache();
	}
	
	// Decode image in background.
	@Override
	protected Bitmap[] doInBackground(BitmapWorkerParameter... params) {
		mParams = params;
		Bitmap[] result = new Bitmap[params.length];
		int i = 0;
		for (BitmapWorkerParameter param : params) {
			String key = getBitmapKey(param);
			Bitmap bmp = getBitmapFromMemCache(key);
			if (bmp == null) {
				bmp = BitmapHelper.decodeSampledBitmap(param.getPath(),
														param.getReqWidth(),
														param.getReqHeight());
				if (param.getCache()) {
					addBitmapToMemoryCache(getBitmapKey(param), bmp);
				}
				Log.d(	TAG,
						"doInBackground(): Bitmap loaded from file, key: " + key);
			} else
				Log.d(	TAG,
						"doInBackground(): Bitmap loaded from cache, key: " + key);
			result[i] = bmp;
			this.publishProgress(new ProgressHolder(i, bmp));
			++i;
		}
		return result;
	}
	
	public static String getBitmapKey(BitmapWorkerParameter param) {
		return param.getPath() + "_"
				+ param.getReqWidth()
				+ "_"
				+ param.getReqHeight();
	}
	
	private void addBitmapToMemoryCache(String key, Bitmap bitmap) {
		if (getBitmapFromMemCache(key) == null && bitmap != null) synchronized (MEM_CHACHE) {
			MEM_CHACHE.put(key, bitmap);
		}
	}
	
	public static Bitmap getBitmapFromMemCache(String key) {
		initMemCache();
		synchronized (MEM_CHACHE) {
			return MEM_CHACHE.get(key);
		}
	}
	
	private static void initMemCache() {
		// initialize cache
		if (MEM_CHACHE == null) {
			final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
			// Use 1/4th of the available memory for this memory cache.
			final int cacheSize = maxMemory / 10;
			MEM_CHACHE = new LruCache<String, Bitmap>(cacheSize) {
				@Override
				protected int sizeOf(String key, Bitmap bitmap) {
					// The cache size will be measured in kilobytes rather than
					// number of items.
					int kbSize = bitmap.getByteCount() / 1024;
					Log.d(	TAG,
							"MEM_CHACHE.sizeOf(): Current cache size [kB]: " + kbSize);
					return kbSize;
				}
			};
		}
	}
	
	@Override
	protected void onProgressUpdate(ProgressHolder... values) {
		BitmapWorkerParameter param = mParams[values[0].TaskNo];
		final ImageView view = param.getImageView();
		if (view != null) {
			view.setImageBitmap(values[0].Bitmap);
			Log.d(	TAG,
					"onProgressUpdate(): Bitmap added to view, path: " + mParams[values[0].TaskNo].getPath());
		}
	}
}
